home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / MOTOROLA / 6805V107 / 68705VIW.PAS < prev    next >
Pascal/Delphi Source File  |  1988-05-06  |  12KB  |  381 lines

  1. {The File-Viewer Window module}
  2.  
  3. Procedure Viewer (Mode : ViewControl);
  4.  
  5. {****************** Direct File I/O Routines ******************************
  6.  We need direct I/O, since Turbo will not recognise a partial record at the
  7.  end of the file (ie if the character count is not an exact multiple of 256
  8.  bytes. This may be circumvented by direct access via DOS}
  9.  
  10. var
  11.    dosrec : Regs;
  12.  
  13. Procedure OpenList;              {Direct OPEN, for Input}
  14. var
  15.    locname : filename;
  16.  
  17. begin
  18.    locname:= listname + #0;      {ASCIIZ for DOS}
  19.    with dosrec do begin
  20.       DS:= Seg(locname[1]);
  21.       DX:= Ofs(locname[1]);
  22.       AX:= $3d00;                {Open for Read}
  23.       MsDos(dosrec);             {We know it will open}
  24.       ListHandle:= AX;
  25.       end
  26.    end;
  27.  
  28. Procedure CloseList;             {Direct CLOSE}
  29. begin
  30.    with dosrec do begin
  31.       BX:= ListHandle;
  32.       AX:= $3e00;
  33.       MsDos(dosrec);
  34.       end
  35.    end;
  36.  
  37. Procedure ReadList (N :integer; var Block : VFdata); {Read 256 bytes at Rec N}
  38. begin
  39.    with dosrec do begin
  40.       BX:= ListHandle;
  41.       AX:= $4200;                 {Seek Record}
  42.       CX:= N shr 8;
  43.       DX:= N shl 8;               {CX:DX = Count of bytes}
  44.       MsDos(dosrec);
  45.       AX:= $3f00;                 {Now Read}
  46.       BX:= ListHandle;
  47.       CX:= VFRmax +1;             {256 bytes}
  48.       DS:= Seg(Block);
  49.       DX:= Ofs(Block);
  50.       MsDos(dosrec);
  51.       end
  52.    end;
  53.  
  54. Function ListSize : integer;      {No. of 256B records, rounded UP}
  55. begin
  56.    with dosrec do begin
  57.       AX:= $4202;                 {Seek EOF}
  58.       BX:= ListHandle;
  59.       CX:= 0;
  60.       DX:= 0;
  61.       MsDos(dosrec);
  62.       ListSize:= (DX shl 8) + ((AX + $ff) shr 8);
  63.       end
  64.    end;
  65.  
  66. {**************************************************************************}
  67.  
  68. const
  69.    null    = 0;                  {Keystroke codes for Viewer commands}
  70.    linup   = 72;                 { They are all Extended sequences}
  71.    linedn  = 80;
  72.    left    = 75;
  73.    right   = 77;
  74.    pgup    = 73;
  75.    pgdn    = 81;
  76.    home    = 71;
  77.    endkey  = 79;
  78.    esckey  = 27;
  79.  
  80.    pgstep  = 21;                 {No. of line to scroll by Page}
  81.  
  82.    Function Find (Recnum :integer) :VFptype;     {Virtual-File Reader}
  83.    {The View-file is implemented as a "virtual file" of records stored in the
  84.     Heap. These records are accessed using a simple hashing algorithm (which
  85.     exploits the locality properties of this application), by this routine.
  86.     The routine returns a pointer to the Heap_record required.}
  87.  
  88.    var
  89.       access : integer;
  90.  
  91.    begin
  92.       access:= recnum mod (MaxCtl+1);             {The hashing function}
  93.       with VFControl[access] do begin
  94.          if (VFrecno <> Recnum) then begin        {Need to read a new record}
  95.             if (VFptr = nil) then new(VFptr);     {Get a buffer, if reqd.}
  96.             VFrecno:= Recnum;                     {This record, now}
  97.             with VFptr^ do
  98.                ReadList(Recnum, VFinfo);          {Direct seek & read}
  99.             end;
  100.          Find:= VFptr;
  101.          end
  102.       end;
  103.  
  104.    Function Same(a, b :VFPosn) :boolean;  {Test if 2 pointers equivalent}
  105.    begin
  106.       Same:= (a[Recordnum] = b[Recordnum]) and
  107.              (a[PosinRecd] = b[PosinRecd]);
  108.       end;
  109.  
  110.    Function Below(a, b :VFPosn) : boolean;
  111.             {Returns TRUE if 'a' is BELOW 'b' in file}
  112.    begin
  113.       Below:= a[Recordnum] > b[Recordnum];
  114.       if a[Recordnum] = b[Recordnum] then
  115.          Below:= a[PosinRecd] > b[PosinRecd];
  116.       end;
  117.  
  118.    Procedure BackOnce (var x : VFPosn);  {Backs up 1 char.}
  119.    begin
  120.       if x[PosinRecd] =0 then begin      {Does NOT check for TOF}
  121.          x[PosinRecd]:= VFRmax;
  122.          x[Recordnum]:= x[Recordnum] -1;
  123.          end
  124.       else
  125.          x[PosinRecd]:= x[PosinRecd] -1;
  126.       end;
  127.  
  128.    Procedure FwdOnce (var x : VFPosn);   {Advance 1 char. only}
  129.    begin
  130.       if x[PosinRecd] < VFRmax then         {Does NOT check for EOF}
  131.          x[PosinRecd]:= x[PosinRecd] +1
  132.       else begin
  133.          x[PosinRecd]:= 0;
  134.          x[Recordnum]:= x[Recordnum] +1;
  135.          end
  136.       end;
  137.  
  138.    Function Data(a : VFPosn) : byte;     {Returns the designated data byte}
  139.    var
  140.       Rptr : VFptype;
  141.  
  142.    begin
  143.       Rptr:= Find( a [Recordnum]);       {Get the data record}
  144.       with Rptr^ do
  145.          Data:= VFinfo[ a[PosinRecd]];
  146.       end;
  147.  
  148.    Procedure Backup(var a : VFPosn; N : integer);
  149.             {Backs-up 'a', N lines - checks for TOF}
  150.    begin
  151.       while ((N > 0) and below(a,TopFile)) do begin
  152.          BackOnce(a);
  153.          if not Same(a,TopFile) then begin
  154.             repeat
  155.                BackOnce(a);
  156.                until Same(a,TopFile) or (Data(a) = ord(CR));
  157.             end;
  158.          if not Same(a,TopFile) then begin
  159.             FwdOnce(a);
  160.             N:= N-1;
  161.             end
  162.          end
  163.       end;
  164.  
  165. Procedure Advance (               {Advance ptr N lines, optionally display}
  166.                    var a : VFPosn;     {File Pointer}
  167.                        N,              {No. of lines to move}
  168.                  Scrline : integer );  {Screen line to OP (or -1) }
  169. var
  170.    outcol : integer;                   {Logical output-col. no.}
  171.      this : char;                      {Current char.}
  172.  
  173.    procedure sendit(x :char);          {Send "x" to CRT}
  174.    var
  175.       loccol : integer;
  176.  
  177.    begin
  178.       loccol:= outcol - ColumnOffset + windsep +1;
  179.       if (windsep < loccol) and (80 >= loccol) then
  180.          CRTbase^[Scrline,loccol,character]:= ord(x);
  181.       outcol:= outcol+1;
  182.       end;
  183.  
  184. begin
  185.    while ((N >0) and Below(BtmFile,a)) do begin
  186.       outcol:= 0;
  187.       if (Scrline >= 0) then begin     {If we output, clear line}
  188.          gotoxy(1,Scrline);
  189.          clreol;
  190.          end;
  191.       repeat                           {Do 1 line}
  192.          this:= chr(Data(a));          {Get a byte}
  193.          if (Scrline >= 0) then begin  {If displaying it...}
  194.             if this = TAB then repeat  {Expand TABs}
  195.                sendit(' ');
  196.                until (outcol mod 8) =0
  197.             else if this >= ' ' then sendit(this);
  198.             end;
  199.          FwdOnce(a);                   {Advance file}
  200.          until (this = CR) or (not Below(BtmFile,a));
  201.       N:= N-1;
  202.       if Scrline > 0 then Scrline:= Scrline +1;
  203.       end
  204.    end;
  205.  
  206. procedure Perform (x :byte);                 {Perform the various functions}
  207. var
  208.    tempoint : VFPosn;
  209.    linectr  : integer;
  210.  
  211.    procedure Showit(Toppoint :VFPosn);       {Non-destructive display}
  212.    begin                                     {Sets new BotScreen}
  213.       clrscr;
  214.       BotScreen:= Toppoint;
  215.       Advance(BotScreen,lastline,1);
  216.       end;
  217.  
  218.    procedure Uponce;
  219.    begin                        {Up One Line}
  220.       if below(TopScreen,TopFile) then begin
  221.          gotoxy(1,1);
  222.          insline;               {Scroll down once}
  223.          Backup(TopScreen,1);
  224.          Backup(BotScreen,1);
  225.          tempoint:= TopScreen;
  226.          Advance(tempoint,1,1);
  227.          end
  228.       end;
  229.  
  230.    procedure Downonce;
  231.    begin                        {Down One Line}
  232.       if below(BtmFile,BotScreen) then begin
  233.          gotoxy(1,1);
  234.          delline;
  235.          Advance(TopScreen,1,-1);
  236.          Advance(BotScreen,1,lastline);
  237.          end
  238.       end;
  239.  
  240. begin
  241.    highvideo;
  242.    case x of
  243.       linup   : Uponce;                              {Up One Line}
  244.  
  245.       linedn  : Downonce;                            {Down One Line}
  246.  
  247.       left    : begin                                {16 Columns Left}
  248.                    if ColumnOffset >= 16 then begin
  249.                       ColumnOffset:= ColumnOffset -16;
  250.                       Showit(TopScreen);
  251.                       end
  252.                    end;
  253.  
  254.       right   : begin                                {16 Columns Right}
  255.                    ColumnOffset:= ColumnOffset +16;
  256.                    Showit(TopScreen);
  257.                    end;
  258.  
  259.       pgup    : for linectr:= 1 to 21 do Uponce;     {21 Lines Up}
  260.  
  261.       pgdn    : for linectr:= 1 to 21 do Downonce;   {21 Lines Down}
  262.  
  263.       home    : begin                                {Top of File}
  264.                    TopScreen:= TopFile;
  265.                    ColumnOffset:= 0;
  266.                    Showit(TopScreen);
  267.                    end;
  268.  
  269.       endkey  : begin                        {End of File}
  270.                    TopScreen:= EndScreen;
  271.                    ColumnOffset:= 0;
  272.                    Showit(TopScreen);
  273.                    end;
  274.       end
  275.    end;
  276.  
  277.  
  278.  
  279. Procedure ViewInitz;                   {Start up the Viewer}
  280. var
  281.    ptr     : integer;
  282.    lastrec : VFptype;
  283.  
  284. begin
  285.    OpenList;                           {Direct OPEN on Listing File}
  286.    FirstView   := true;                {Set up variables}
  287.    ColumnOffset:= 0;
  288.    for ptr:= 0 to MaxCtl do
  289.       with VFControl[ptr] do begin
  290.          VFptr  := nil;                {Clean out the Control Table}
  291.          VFrecno:= -1;
  292.          end;
  293.    TopFile[Recordnum]:= 0;             {Set up file pointers}
  294.    TopFile[PosinRecd]:= 0;
  295.    BtmFile[Recordnum]:= ListSize -1;
  296.    lastrec:= Find(BtmFile[Recordnum]); {Read the final record}
  297.    with lastrec^ do begin
  298.       ptr:= 0;
  299.       repeat                           {Locate the final CR}
  300.          if VFinfo[ptr] =ord(CR) then BtmFile[PosinRecd]:= ptr;
  301.          ptr:= ptr+1;
  302.          until ((ptr > VFRmax) or (VFinfo[ptr] =ord(ENDFILE)));
  303.       end;
  304.    if BtmFile[PosinRecd] < VFRmax then  { Now point BtmFile at true EOF}
  305.       BtmFile[PosinRecd] := BtmFile[PosinRecd] +1;
  306.    EndScreen:= BtmFile;
  307.    Backup(EndScreen, lastline);    {Final top-of-screen locn.}
  308.    end;
  309.  
  310. Procedure ViewTheFile;           {The main Viewing Function}
  311.    Procedure DoViewCmnd (firstcmnd : byte);    {Do a command}
  312.    var
  313.       dothis : byte;                {The command to do}
  314.  
  315.       function viewcmnd : byte;        {Get/validate Command}
  316.       const
  317.          extncommands : set of byte =[ null,   linup,  linedn, left,   right,
  318.                                        pgup,   pgdn,   home,   endkey];
  319.       var
  320.          keyc : char;
  321.          extn : boolean;
  322.  
  323.       begin
  324.          repeat
  325.             read(kbd,keyc);                       {Get some key}
  326.             extn:= keypressed and (keyc = ESC);
  327.             if extn then read(kbd,keyc);          {Get extended key, if any}
  328.             until ((extn and (ord(keyc) in extncommands)) or
  329.                   ((not extn) and (keyc = ESC)));
  330.          viewcmnd:= ord(keyc);
  331.          end;                          {of Function VIEWCMND}
  332.  
  333.    begin                            {Main body of DoViewCmnd}
  334.       dothis:= firstcmnd;
  335.       repeat
  336.          Perform (dothis);          {Perform the command}
  337.          dothis:= viewcmnd;         {Next one}
  338.          until dothis = esckey;
  339.       end;                          {of Procedure DOVIEWCMND}
  340.  
  341. const
  342.    brp1 = '{|X|Y} Line ~: {|[|Z} 16 cols ~: ';
  343.    brp2 = '{PgUp PgDn} Screen ~: {Home} Start ~: ';
  344.    brp3 = '{End} Bottm ~: {ESC}=Emulate';
  345.  
  346. begin                            {Main body of ViewTheFile}
  347.    window(1,1,80,25);
  348.    savewindow(debugwind);
  349.    promptline(brp1 + brp2 + brp3);
  350.    if FirstView then begin
  351.       FirstView:= false;         {Draw it the first time}
  352.       firstscreen;
  353.       DoViewCmnd (home);
  354.    end
  355.    else begin
  356.       showwindow(viewind);
  357.       DoViewCmnd (null);
  358.       end;
  359.    savewindow(viewind);
  360.    pulldebug(true);              {Then get DEBUG back}
  361.    end;
  362.  
  363. Procedure ViewFinish;            {Done Viewing - Clean up}
  364. var
  365.    ptr : integer;
  366.  
  367. begin
  368.    CloseList;
  369.    for ptr:= 0 to MaxCtl do
  370.       with VFcontrol[ptr] do
  371.          if (VFptr <> nil) then dispose(VFptr);
  372.    end;
  373.  
  374. begin
  375.    case Mode of
  376.       Initz  : ViewInitz;
  377.       View   : ViewTheFile;
  378.       Finish : ViewFinish;
  379.       end
  380.    end;
  381.